package com.mobile.web.user;

import com.alibaba.fastjson.JSON;
import com.mobile.service.dto.AuthDTO;
import com.mobile.service.dto.UserDTO;
import com.mobile.service.dto.UserQueryDTO;
import com.mobile.service.inter.system.UserService;
import com.mobile.web.base.BaseController;
import com.mobile.web.config.util.Jurisdiction;
import com.mobile.util.RedisUtil;
import com.mobile.util.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import redis.clients.jedis.Jedis;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 用户权限API接口
 */
@RestController
@RequestMapping("/user")
public class UserController extends BaseController {
    @Autowired
    private UserService userService;
    @Value("${static.file.path.course.image}")
    private String imageTypePath;
    @Value("${static.file.path}")
    private String path;
    /**
     * 用户列表查询（分页）
     */
    @PostMapping("/getUserListPage")
    //@RequiresPermissions("userinfo:read:1")
    public Object getUserListPage(UserQueryDTO userQueryDTO) {
        PageData user = this.getUser();
        String isAdmin = (String) user.get("is_admin");
        Map<String, Object> map = new HashMap<>();

        try {
            PageResult<UserDTO> userPage = userService.getUserListPage(userQueryDTO, user);
            map.put("page", userPage);
            map.put("data", userPage.getPageDatas());
            map.put("showLeftTree", userPage.get("showLeftTree"));
            if ("0".equals(isAdmin)) {
                map.put("adminVisible", false);
            } else {
                map.put("adminVisible", true);
            }
            map.put("QX", Jurisdiction.getHC(this.getUserCode(),"userinfo"));
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_SUCCESS);
        } catch (Exception e) {
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_EXCEPTION);
            map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0016"));
            logger.error(e.getMessage(), e);
        }

        return AppUtil.returnObject(map);
    }




    /**
     * 查询角色具有的功能权限，如果该角色和当前登录用户角色相同则获取当前登录用户最大权限
     */
    @GetMapping("/getMenuAuthByRole")
    //@RequiresPermissions({"userinfo:add:1", "userinfo:edit:1"})
    public Object getMenuAuthByRole() {
        Map<String, Object> map = new HashMap<>();
        PageData pd = this.getPageData();
        int userRole = (Integer) this.getUser().get("user_role");
        int roleId = Integer.parseInt( pd.get("roleId").toString());

        List<PageData> tree = null;
        try {
            if (userRole != roleId) {
                tree = userService.getMenuAuthByRole(roleId);
                List<String> authIds = userService.getRoleAuthByRoleId(roleId);
                map.put("authIds", authIds);
            } else {
                tree = userService.getMenuAuthByUser(pd.getString("createUser"));
                List<String> authIds = userService.getUserAuthByUserCode(pd.getString("createUser"));
                map.put("authIds", authIds);
            }
            map.put("data", tree);
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_SUCCESS);
        } catch (Exception e) {
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_EXCEPTION);
            map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0016"));
            logger.error(e.getMessage(), e);
        }

        return AppUtil.returnObject(pd, map);
    }

    /**
     * 新增用户和分配的权限
     */
    @PostMapping("/addUser")
    //@RequiresPermissions("userinfo:add:1")
    public Object addUser() {
        Map<String, Object> map = null;
        PageData pd = this.getPageData();
        pd.put("user", this.getUser());

        try {
            List<PageData> dts = JSON.parseArray(pd.getString("list"), PageData.class);
            //判断前端人员批量数据中 手机号/账号/工号是否存在重复
            try {
                dts.stream().collect(Collectors.toMap(t -> t.getString("userCode"), Function.identity()));
                dts.stream().collect(Collectors.toMap(t -> t.getString("mobilePhone"), Function.identity()));
            } catch (IllegalStateException e) {
                map = new HashMap<>();
                map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_FAILED);
                map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0219"));
                logger.error(e.getMessage(), e);
                return AppUtil.returnObject(map);
            }
            dts.forEach(t-> t.putAll(pd));
            map = userService.addUser(dts);
        } catch (Exception e) {
            map = new HashMap<>();
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_EXCEPTION);
            map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0016"));
            logger.error(e.getMessage(), e);
        }

        return AppUtil.returnObject(map);
    }

    /**
     * 修改用户信息
     * @return
     */
    @PostMapping("/updateUserWithAuth")
    //@RequiresPermissions("userinfo:edit:1")
    public Object updateUserWithAuth() {
        Jedis jedis = RedisUtil.getJedis();
        PageData pd = this.getPageData();
        Map<String, Object> map = null;
        pd.put("user", this.getUser());
        try {
            map = userService.updateUserWithAuth(pd,jedis);
        } catch (Exception e) {
            map = new HashMap<>();
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_EXCEPTION);
            map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0016"));
            logger.error(e.getMessage(), e);
        }finally {
            jedis.close();
        }
        return AppUtil.returnObject(pd, map);
    }


    /**
     * 删除用户
     * @return
     */
    @GetMapping("/removeUser")
    //@RequiresPermissions("userinfo:delete:1")
    public Object removeUser() {
        Map<String, Object> map = new HashMap<>();
        PageData pd = this.getPageData();

        try {
            userService.removeUser(pd);
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_SUCCESS);
            map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("I0010"));
        } catch (Exception e) {
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_EXCEPTION);
            map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0016"));
            logger.error(e.getMessage(), e);
        }

        return AppUtil.returnObject(pd, map);
    }

    /**
     * 根据用户账号获取用户信息和分配的权限
     * @return
     */
    @PostMapping("/getUserWithAuthByCode")
    //@RequiresPermissions("userinfo:edit:1")
    public Object getUserWithAuthByCode() {
        PageData pd = this.getPageData();
        String thisRoleCode = this.getUser().getString("role_code");
        String userCode = pd.getString("userCode");
        String roleCode = pd.getString("roleCode");
        Integer userRole = Integer.valueOf(pd.get("userRole").toString());
        Map<String, Object> map = new HashMap<>();

        try {
            PageData userByCode = userService.getUserByCode(userCode);
            if (Objects.isNull(userByCode)) {
                map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_FAILED);
                map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0001"));
                return map;
            }
            map = userService.getUserWithAuthByCode(userCode);
            if (Const.ROLE_CODE_MARKET.equals(thisRoleCode) && Const.ROLE_CODE_DETONA.equals(roleCode)) {
                List<PageData> roleAuthList = userService.getMenuAuthByRole(userRole);
                map.put("roleAuthList", roleAuthList);
            } else {
                //查询用户所有的权限树
                //当前查询的用户角色与登录用户角色相同，查询登录用户的权限树
                if (thisRoleCode.equals(roleCode)) {
                    List<PageData> userAuthList = userService.getMenuAuthByUser(pd.getString("createUser"));
                    map.put("roleAuthList", userAuthList);
                    List<String> auths = (List<String>) map.get("auths");
                    List<String> authIds = new ArrayList<>();
                    this.restAuthIds(auths, userAuthList, authIds);
                    map.put("auths", authIds);
                } else {//当前查询的用户角色与登录用户角色不相同，查询角色的权限树
                    List<PageData> userAuthList = userService.getMenuAuthByRole(userRole);
                    map.put("roleAuthList", userAuthList);
                    List<String> auths = (List<String>) map.get("auths");
                    List<String> authIds = new ArrayList<>();
                    this.restAuthIds(auths, userAuthList, authIds);
                    map.put("auths", authIds);
                }
            }
        } catch (Exception e) {
            map = new HashMap<>();
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_EXCEPTION);
            map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0016"));
            logger.error(e.getMessage(), e);
        }

        return AppUtil.returnObject(pd, map);
    }

    private void restAuthIds(List<String> auths, List<PageData> userAuthList, List<String> authIds) {
        for (PageData data : userAuthList) {
            List<PageData> children = (List<PageData>) data.get("children");
            if (StringUtil.isEmptyList(children)) {
                if (auths.contains(data.getString("key"))) {
                    authIds.add(data.getString("key"));
                }
            } else {
                //递归调用
                this.restAuthIds(auths, children, authIds);
            }
        }
    }

    /**
     * 启用/禁用账户
     * isLocked：账户锁定标志（0：禁用  1：启用  2：删除）
     * @return
     */
    @PostMapping("/lockedUser")
    //@RequiresPermissions("userinfo:edit:1")
    public Object lockedUser() {
        PageData pd = this.getPageData();
        Map<String, Object> map = new HashMap<>();

        try {
            userService.lockedUser(pd);
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_SUCCESS);
            map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("I0012"));
        } catch (Exception e) {
            map = new HashMap<>();
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_EXCEPTION);
            map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0016"));
            logger.error(e.getMessage(), e);
        }

        return AppUtil.returnObject(pd, map);
    }

    /**
     * 获取登录用户信息
     */
    @PostMapping("/getLoginUserInfo")
    public Object getLoginUserInfo() {
        PageData user = this.getUser();
        Map<String, Object> map = new HashMap<>();

        try {
            map.put("data", userService.getLoginUserInfo(user.getString("user_code")));
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_SUCCESS);
        } catch (Exception e) {
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_EXCEPTION);
            map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0016"));
            logger.error(e.getMessage(), e);
        }

        return AppUtil.returnObject(map);
    }

    /**
     * 修改用户个人信息
     */
    @PostMapping("/updateUserInfo")
    public Object updateUserInfo() {
        PageData pd = this.getPageData();
        Map<String, Object> map = new HashMap<>();

        try {
            String userCode = pd.getString("userCode");
            //验证修改的手机号是否存在,手机号相同但是用户code不同，代表手机号重复
            PageData userPhone = userService.getUserByPhone(pd.getString("mobilePhone"));
            if (null != userPhone && !userCode.equals(userPhone.getString("user_code"))) {
                map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_FAILED);
                map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0004", "该手机号"));
                return map;
            }

            userService.updateUserInfo(pd);
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_SUCCESS);
        } catch (Exception e) {
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_EXCEPTION);
            map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0016"));
            logger.error(e.getMessage(), e);
        }
        return AppUtil.returnObject(map);
    }

    /**
     * 修改个人密码
     */
    @PostMapping(value = "/updatePassword")
    @ResponseBody
    public Object updatePassword(){
        PageData pd = this.getPageData();
        PageData user = this.getUser();
        Map<String, Object> map = new HashMap<>();
        try {
            // 根据当前登录用户手机号码获取用户信息
            PageData pageData = userService.getUserByPhone(user.getString("mobile_phone"));
            // 判断旧密码输入是否正确
            String oldPass = EncryptUtil.encrypt(pd.get("oldPasswd").toString().trim() + pageData.getString("secret_key"));
            String old = pageData.getString("user_password");
            if (!oldPass.equals(old)){
                map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_FAILED);
                map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0014"));
                return AppUtil.returnObject(new PageData(), map);
            }else if((EncryptUtil.encrypt(pd.getString("passwd") + pageData.getString("secret_key"))).equals(pageData.getString("user_password"))){
                // 确认新旧密码是否相同
                map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_FAILED);
                map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0015"));
                return AppUtil.returnObject(new PageData(), map);
            }
            // 获取密码编译字符串
            pd.put("secret_key",pageData.getString("secret_key"));
            // 获取当前用户手机号
            pd.put("phone",user.getString("mobile_phone"));
            int status = userService.updatePassword(pd);
            map.put(Const.ACTION_RESULT,Const.ACTION_RESULT_SUCCESS);
            map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("I0009"));
            map.put("data",status);
        } catch (Exception e) {
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_EXCEPTION);
            map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0016"));
            logger.error(e.getMessage(), e);
        }
        return AppUtil.returnObject(new PageData(), map);
    }



//    /**
//     * 用户组织树
//     */
//    @RequestMapping("/userTree")
//    //@RequiresPermissions("userinfo:read:1")
//    public Object userTree() {
//        Map<String, Object> map = new HashMap<>();
//        try {
//            List<PageData> pdsList = userService.getUserTree();
//            map.put("data", pdsList);
//            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_SUCCESS);
//        } catch (Exception e) {
//            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_EXCEPTION);
//            map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0016"));
//            logger.error(e.getMessage(), e);
//        }
//        return AppUtil.returnObject(map);
//    }
    /**
     * 读取excel中的用户信息
     * @return
     */
    @PostMapping("/getUserListByExcel")
    //@RequiresPermissions("userinfo:read:1")
    public Object analysisExcel(MultipartFile file) {
        Map<String, Object> map = new HashMap<>();
        try {
            //判断文件格式
            String format = file.getOriginalFilename().split("\\.")[1];
            if (!("xlsx".equals(format) || "xls".equals(format))) {
                map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_FAILED);
                map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0209"));
                return AppUtil.returnObject(map);
            }
            List<PageData> pdsList = ExcelUtils.excelToShopIdList(file.getInputStream());
            map.put("data", pdsList);
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_SUCCESS);
        } catch (Exception e) {
            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_EXCEPTION);
            map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0016"));
            logger.error(e.getMessage(), e);
        }
        return AppUtil.returnObject(map);
    }
//    /**
//     * 根据接受到的权限返回对应权限值
//     * @return
//     */
//    @RequestMapping("/getUserAuths")
//    //@RequiresPermissions("userinfo:read:1")
//    public Object getUserAuths() {
//        PageData pd = this.getPageData();
//        Map<String, Object> map = new HashMap<>();
//        try {
//            map.put("QX", Jurisdiction.getHCs(this.getUserCode(),Arrays.asList(pd.get("auths").toString().split(","))));
//            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_SUCCESS);
//        } catch (Exception e) {
//            map.put(Const.ACTION_RESULT, Const.ACTION_RESULT_EXCEPTION);
//            map.put(Const.ACTION_MESSAGE, MessageUtil.getMessage("E0016"));
//            logger.error(e.getMessage(), e);
//        }
//        return AppUtil.returnObject(map);
//    }

}
